let sum = "";
let 式子 = '';
let 结果 = '';
let 点击等号 = false
Page({
  data: {
    result: 结果,
    posture: 式子,
  },
  onLoad() {
    this.setData({
      jingyin: wx.getStorageSync('jingyin')
    })
  },
  onReady() {
    wx.setInnerAudioOption({
      obeyMuteSwitch: false
    })
  },
  onShow() {
    this.innerAudioContext = wx.createInnerAudioContext({
      useWebAudioImplement: false // 是否使用 WebAudio 作为底层音频驱动，默认关闭。对于短音频、播放频繁的音频建议开启此选项，开启后将获得更优的性能表现。由于开启此选项后也会带来一定的内存增长，因此对于长音频建议关闭此选项
    })
  },
  onHide() {
    this.innerAudioContext.destroy()
  },
  onShareAppMessage() {
    return {
      title: "便携计算器",
      path: "/pages/calculationTools/pages/calculator/index",
      imageUrl: '/images/function_icon/jisuanqi.png',
    }
  },
  onShareTimeline() {
    return {
      title: '便携计算器',
      imageUrl:'/images/function_icon/jisuanqi.png'
    }
  },
  /**
   * 手动输入式子
   * @param {*} e 
   */
  postureInput(e) {
    式子 = e.detail.value
    this.calc()
    this.setData({
      posture: 式子,
      result: 结果
    })
  },
  /**
   * 按键输入
   * @param {*} e 
   */
  numberClick(e) {
    let {
      num
    } = e.target.dataset
    this.innerAudioContext.src = '/pages/calculationTools/audios/dianji.mp3'
    switch (num) {
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        if (式子.includes('=')) sum = 式子 = 结果 = ''
        式子 += num
        this.calc()
        break;
      case '.':
        if (式子.includes('=')) sum = 式子 = 结果 = ''
        let st0 = 式子.substring((式子.length) - 1, (式子.length));
        console.log(st0)
        if (式子 == "") {
          式子 += "0.";
        } else if (st0 == "+" || st0 == "-" || st0 == "×" || st0 == "÷" || st0 == "(") {
          式子 += "0.";
        } else if (st0 == ")") {
          式子 += "×0.";
        } else {
          式子 += ".";
        }
        break;
      case '+':
      case '-':
      case '×':
      case '÷':
      case '^':
      case '%':
        if (!式子) return
        if (式子.includes('=')) sum = 式子 = 结果
        式子 += num
        break;
      case 'AC':
        sum = 式子 = 结果 = ''
        this.innerAudioContext.src = '/pages/calculationTools/audios/guiling.mp3'
        break;
      case 'delete':
        if (!式子) return
        // 式子 = 式子.replace(/=/g, '')
        式子 = 式子.substring(0, 式子.length - 1)
        this.calc()
        break;
      case '(':
      case ')':
        if (式子.includes('=')) sum = 式子 = 结果 = ''
        式子 += num
        this.calc()
        break;
      case '=':
        if (!式子) return
        if (!式子.includes('=')) 式子 += '='
        this.calc()
        break;
      case 'jingyin':
        this.setData({
          jingyin: !this.data.jingyin
        })
        wx.setStorageSync('jingyin', this.data.jingyin)
        break;
      default:
        console.log('默认行为')
        break;
    }
    if (this.data.jingyin) {
      this.innerAudioContext.play()
    }
    this.setData({
      posture: 式子,
      result: 结果
    })
  },
  /**
   * 计算结果
   */
  calc() {
    sum = 式子.replace(/×/g, '*').replace(/÷/g, '/').replace(/=/g, '').replace(/%/g, '*(1/100)')
    try {
      matchingBracket_Opera()
    } catch (error) {
      结果 = '错误'
    }
  },
})

function TNumber2(value) {
  let arr = ["^", "*", "√x", "%", "/%(余)"]
  let arrindex = ["^", "*", "^(1/2)", "*(1/100)", "%"]
  //当存在先点击小数点后，默认输出为0.
  for (let i = 0; i < arr.length; i++) {
    if (value == arr[i]) {
      value = arrindex[i];
      sum += value;
    }
  }
  if (value == ".") {
    let str = sum + value;
    let st0 = str.substring((str.length) - 2, (str.length) - 1);
    if (sum == "") {
      value = "0.";
      sum += value;
    } else if (st0 == "+" || st0 == "-" || st0 == "*" || st0 == "/" || st0 == "(") {
      value = "0.";
      sum += value;
    } else if (st0 == ")") {
      value = "*0.";
      sum += value;
    } else {
      value = ".";
      sum += value;
    }

  }
}

function TNumber(value) {
  sum += value;

}

function Clear() {
  sum = "";
  结果 = '';
}
/**
 * 弃用eval工具，真正实现运算逻辑之前的使用 解译字符串，如果可计算，直接返回结果
 */
function get_res_ByEval() {
  if (sum.indexOf(".")) {
    let a = Number(eval(sum));
    let b = (eval(sum));
    var y = String(b).indexOf(".") + 1;
    var count = 0; //小数点位置；
    count = b.length - y;
    if (count >= 10) {
      sum + "=" + parseFloat(a * 10000000).toFixed(7);
    } else {
      sum + "=" + eval(sum);
    }

  }
}

function BackOne(value) {
  var str = "";
  sum += value;
  str = sum;
  sum = str.substring(0, ((str.length) - 5)); //实现delete字符串功能，始终是最后的
}
/*------------------ 工作区间----------- */
/**
 * 括号匹配与运算 必须左括号等于右括号 
 * Brackets
 */
function matchingBracket_Opera() {
  //7-7+2*(9-1*(4+1*(1-2)+(2*3)+1))
  let string = sum
  //倍乘规范化2（1-2）=>2*（1-2）
  let str_0_arr = [],
    trs_0_str = ""
  for (let i = 0; i < string.length; i++) {
    let bool = IsOpChar(string[i - 1])
    if (string[i] == "(" && string[i - 1] != "." || string[i] == "（") {
      if (bool == false && i > 0) {
        str_0_arr.push("*(")
      } else {
        str_0_arr.push("(")
      }
    } else {
      str_0_arr.push(string[i])
    }
  }
  for (let j = 0; j < str_0_arr.length; j++) {
    trs_0_str = trs_0_str + str_0_arr[j]
  }
  // // console.log(trs_0_str)
  string = trs_0_str
  //接近首位的括号可能需要变号
  let str_0_st = string[0]
  if (str_0_st == "+" || str_0_st == "-")
    string = "0" + string
  else {
    string = "0+" + string
  }
  //乘方替换
  string = string.replace(/\*\*/g, '^');
  string = string.replace(/÷/g, '/')
  /* 记录匹配位置 */
  //最优先的级别是括号之间没有括号，再去掉换成数字，然后再次计算！！！！！
  let bool = "可以匹配";

  /**
   * 括号优先级匹配  理论上可以去掉全部括号计算，但是验证起来麻烦，计算替换后长度变化混乱，本人没解决，因此迭代每一个优先项，增加了复杂度
   * @param {*} string 
   * @returns [res_LB_index,bool] 
   */
  function macth_Br(string) {
    let str = string,
      leftB_arr_index = [],
      rightB_arr_index = [],
      str_L_R = [];
    // // console.log(str)
    let leftB_N = 0,
      rightB_N = 0
    for (let i = 0; i < str.length; i++) {
      if (str[i] == "(" || str[i] == "（") {
        leftB_N = leftB_N + 1
        leftB_arr_index.push(i)
        str_L_R.push([i, "左"])
      } else if (str[i] == ")" || str[i] == "）") {
        rightB_N = rightB_N + 1
        rightB_arr_index.push(i)
        str_L_R.push([i, "右"])
      }
    }
    // console.log("左括号索引" + leftB_arr_index)
    // console.log("右括号索引" + rightB_arr_index)
    // console.log("水平匹配合并后的索引" + str_L_R)
    if (leftB_N > 0) {
      if (leftB_arr_index.length != rightB_arr_index.length || str_L_R[0][1] == "右")
        bool = "输入括号有误，无法匹配括号"
    }

    /**
     * 水平匹配法 ，通用方法【由左到右】（）（（））（）
     * @param {*} str 
     */
    function levelMatch(index_LB) {
      let n = 0,
        L_R_res = [];
      let m = 0

      function fisrtCheck() { //匹配规则 配对的左索引的必须比右括号索引小
        for (let i = 0; i < rightB_arr_index.length; i++) {
          if (leftB_arr_index[i] > rightB_arr_index[i]) {
            bool = bool == "无法匹配"
            break
          }
        }
      }
      fisrtCheck()
      if (index_LB.length > 2 && bool == "可以匹配") {
        for (let i = 0; i < index_LB.length; i++) {

          if (index_LB[i][1] == "左") {
            // // console.log("左边匹配索引" + i)
            //级别记录
            m = 0, n = 0
            for (let j = i + 1; j < index_LB.length; j++) {
              if (index_LB[j][1] == "左") {
                n = n + 1
                // // console.log("nnn是" + n)
                continue
              } else {
                //
                if (m == n) {
                  L_R_res.push([index_LB[i][0], index_LB[j][0], n]);
                  // // console.log("成功匹配" +c )
                  break;
                }
                if (m != n && j == index_LB.length - 1) {
                  bool = "无法匹配！"
                  break;
                }


                m = m + 1
                // // console.log("mmm是" + m)
              }
            }

          } else {
            continue
          }
        }
      } else {
        L_R_res.push([index_LB[0][0], index_LB[1][0], n]);
      }

      //分级定序匹配  排序
      let res_LB_index = []
      // console.log("水平匹配索引" + L_R_res)
      for (let i = 0; i < L_R_res.length - 1; i++) {
        for (let j = i + 1; j < L_R_res.length; j++) {
          let a = L_R_res[i][2],
            b = L_R_res[j][2]
          if (a > b) {
            let t = L_R_res[i]
            L_R_res[i] = L_R_res[j]
            L_R_res[j] = t
          }
        }
      }
      // console.log("排序后匹配索引" + L_R_res)
      for (let i = 0; i < L_R_res.length; i++) {
        res_LB_index.push([L_R_res[i][0], L_R_res[i][1]])
      }
      // console.log("最终优先匹配计算 索引" + res_LB_index)
      //secondCheck
      for (let i = 0; i < res_LB_index.length; i++) {
        if (res_LB_index[i][1] - res_LB_index[i][0] == 1) {
          bool = "式子存在空括号，无法计算！"
        }
      }
      return [res_LB_index[0], bool]
    }

    let res_LB_index_bool = [, bool]
    if (leftB_N > 0) {
      res_LB_index_bool = levelMatch(str_L_R)
    } else {
      bool = "式子不存在括号"
      res_LB_index_bool[1] = "式子不存在括号"
    }

    // console.log(bool)
    // console.log(res_LB_index_bool)

    return res_LB_index_bool

  }
  let index_bool = macth_Br(string);
  bool = index_bool[1]
  /**
   * 括号与式子运算
   */
  function Brackets_Operation(str, bool) {
    let str_replace = str,
      n = 0
    if (bool != "可以匹配") {
      if (bool == "式子不存在括号") {
        primaryOperation(str)
      }
    } else {
      let xy_index_bool
      let [x, y] = index_bool[0]
      // console.log("替换开始") //1+3(1-2)-6(7-(7))macth_Br(string)[0][0]
      while (isIndexOfchar(str_replace, "(") == true || isIndexOfchar(str_replace, "（") == true) {

        // console.log(str_replace + "--------需要去括号的----------")
        // console.log([x, y] + "--------去括号----------")
        // console.log("需要去括号的替换多项式" + str_replace)
        let xy = str_replace.slice(x + 1, y)
        // console.log(x + "截取以后" + y + "多项式" + xy)
        let res_xy = primaryOperation(xy),
          st = x,
          ed = y
        // console.log("计算多项式" + res_xy)
        str_replace = stringReslpace(str_replace, st, ed, res_xy)
        xy_index_bool = macth_Br(str_replace)
        bool = xy_index_bool[1]
        // console.log("截取xy" + xy_index_bool[0])
        if (bool == "式子不存在括号") {
          break
        }
        x = xy_index_bool[0][0], y = xy_index_bool[0][1]
        // console.log("计算以后的" + str_replace)
      }
      // console.log("最后计算计算的" + str_replace)
      primaryOperation(str_replace)
    }
  }

  //负号问题，替换的时候，
  Brackets_Operation(string, bool)
}

/** 初等运算 primary operation 不含括号，只有加减乘除、乘方、开根 求余 包含小数
 * @param {*} str 不含括号的式子  初等式子 0+xy或0-xy
 * @returns res_N 计算结果
 */
function primaryOperation(str) {
  let string0 = str
  let str_0_st = str[0]
  let str_arr = []
  //乘方替换
  str = str.replace(/\*\*/g, '^');
  str = str.replace(/÷/g, '/')

  // console.log("初等式子计算的式子" + str)

  let F_add_Sub = [],
    F_a_s_index = [],
    F_ad_Sub_str = ""
  let factor_arr = []
  //因式与符号与数字再次组合 顺序由谁开头决定
  for (let i = 0; i < str.length; i++) {
    str_arr.push(str[i])
    if (str[i] == "+" || str[i] == "-") {
      F_add_Sub.push(str[i])
      F_a_s_index.push(i)
      F_ad_Sub_str = F_ad_Sub_str + str[i]
    }

  }
  str = str.replace(/\+/g, "FF")
  str = str.replace(/\-/g, "FF")
  factor_arr = str.split("FF")

  let res_fac_Num = []
  // console.log("加减符号数组" + F_add_Sub)
  // console.log("因式数组" + factor_arr)
  //原始字符串数组 
  for (let i = 0; i < factor_arr.length; i++) {
    //每个因式求结果 Num_arr_fac
    let str_fac = factor_arr[i]
    let fac_F_str = ""
    let fac_F_arr_str = [],
      fac_f_index_arr = [],
      fac_Num_arr = []
    for (let j = 0; j < str_fac.length; j++) {
      let item = str_fac[j]
      let bool = IsOpChar(item)
      if (bool == true) {
        fac_F_str = fac_F_str + item
        fac_f_index_arr.push(j)
      }
    }
    fac_F_arr_str.push(fac_F_str)
    str_fac = str_fac.replace(/\^/g, "FFF")
    str_fac = str_fac.replace(/\*/g, "FFF")
    str_fac = str_fac.replace(/\//g, "FFF")
    str_fac = str_fac.replace(/\%/g, "FFF")
    fac_Num_arr = str_fac.split("FFF")
    // console.log("第" + i + "因式数组数字" + fac_Num_arr)
    // console.log("第" + i + "因式数组运算符顺序" + fac_F_str)
    if (fac_F_str != "") {
      //乘方最高级运算
      while (fac_F_str.indexOf("^") != -1) {
        // console.log("去除^号前" + fac_F_str)
        let str = "^"
        let x = fac_F_str.indexOf(str)
        let y = fac_Num_arr[x] ** fac_Num_arr[x + 1]
        // console.log(y)
        // console.log(x)
        //数组删除
        fac_Num_arr.splice(x, 1)
        fac_Num_arr[x] = y
        fac_F_str = delString(fac_F_str, str)
      }
      // console.log("去除^号以后" + fac_F_str)
      for (let a = 0; a < fac_F_str.length; a++) {

        let str = fac_F_str[a]
        let x = fac_F_str.indexOf(str)
        let y = -9999
        if (str == "/") {
          y = fac_Num_arr[x] / fac_Num_arr[x + 1]
        }
        if (str == "*")
          y = fac_Num_arr[x] * fac_Num_arr[x + 1]
        if (str == "%")
          y = fac_Num_arr[x] % fac_Num_arr[x + 1]
        // console.log(y)
        // console.log(x)
        //数组删除
        fac_Num_arr.splice(x, 1)
        fac_Num_arr[x] = y
        fac_F_str = delString(fac_F_str, str)
        // console.log("去除运算符*%/以后")
        // console.log(fac_Num_arr)
        // console.log(fac_F_str)
        a--
      }

    }
    res_fac_Num.push(fac_Num_arr)

  }
  // console.log("因式结果数组" + res_fac_Num)
  // console.log("原始式子加减数组" + F_ad_Sub_str)
  // if (str_0_st == "+" || str_0_st == "-")
  //     res_fac_Num.unshift(0)
  for (let nn = 0; nn < F_ad_Sub_str.length; nn++) {
    let str = F_ad_Sub_str[nn]
    let x = F_ad_Sub_str.indexOf(str)
    let y = -9999
    if (str == "+") {
      y = Number(res_fac_Num[x]) + Number(res_fac_Num[x + 1])
    }
    if (str == "-")
      y = Number(res_fac_Num[x]) - Number(res_fac_Num[x + 1])
    // console.log(y)
    // console.log(x)
    //数组删除
    res_fac_Num.splice(x, 1)
    res_fac_Num[x] = y
    F_ad_Sub_str = delString(F_ad_Sub_str, str)
    // console.log("去除运算符+-以后")
    // console.log(res_fac_Num)
    // console.log(F_ad_Sub_str)
    nn--
  }
  // console.log("结果数组" + res_fac_Num)

  结果 = res_fac_Num[0] + ''
  // document.getElementById("txt").value = string0 + "=" + res_Num;
  return 结果
}
/**  字符串删除字符
 * @param string{string} 处理字符串
 * @param str{string} 指定字符
 * @return {string} 删除指定第一个字符以后的字符
 */
function delString(string, str) {
  let arr = []
  let n = 0
  for (let i = 0; i < string.length; i++) {
    if (string[i] == str) {
      n = n + 1
    }
    if (string[i] != str || n != 1) {
      arr.push(string[i])
    }
  }
  let res = ""
  for (let i = 0; i < arr.length; i++) {
    res = res + arr[i]
  }
  return res

}
/**
 * 根据索引替换字符串
 * @param {*} string  原始字符串
 * @param {*} indexSt 开始索引
 * @param {*} indexEd 结束索引
 * @param {*} str_ 替换字符组
 * @returns res_str nn 索引实际变化  新的字符串 严格来说，长度发生变化，需要整体  看待   后面需要统一正则替换
 */
function stringReslpace(string, indexSt, indexEd, str_) {
  let oldarr = [],
    newarr = [],
    res_str = ""

  let _str = -Number(str_)
  // console.log("相反数变号" + _str)

  for (let i = 0; i < string.length; i++) {
    oldarr.push(string[i])
  }
  /**  **注意**    JS字符串不能根据索引改变
   *  去掉优先级括号  确定因式前的+-,变号 Opposite number
   * @param {*} oldarr 计算的整体数组   eg. 1-(1-2)+((7+0)*1+(1-2(1-2)))
   * @param {*} indexSt 替换开始索引
   */
  function removeBr_Opposite_number(oldarr, indexSt) {
    let n = 0,
      m = 0
    // console.log("变号处理前的字符" + oldarr)

    for (let i = indexSt - 1; i >= 0; i--) {
      // console.log("我在" + i + "开始变号" + oldarr[i])
      let item = oldarr[i]
      if (i == indexSt - 1 && item == "(" || item == "（") {
        // console.log("我没变号" + oldarr[i])
        break
      } else if (item == ")" || item == "）" || item == "(" || item == "（") {
        if (item == ")" || item == "）")
          n = n + 1
        if (n >= 1 && item == "(" || item == "（") {
          m = m + 1
        }
      } else if (IsInt_char(item)) {
        // console.log("纯数字，我需要下一步！" + item)
        // console.log("验证！" + oldarr[i - 3])
        continue
      } else if (IsOpChar(item)) {
        // console.log("运算符是！" + item + IsOpChar(item))

        if (item == "+" && m == n) {
          // console.log("我在" + i + "变号完成1");
          oldarr[i] = "-";
          break
        } else if (item == "-" && m == n) {
          // console.log("我在" + i + "变号完成2");
          oldarr[i] = "+";
          break
        } else {
          // console.log("高级运算符" + item)
          continue
        }
      }
    }
    // console.log("变号处理后的字符" + oldarr)
    return oldarr
  }

  //相反数大于0 变号


  if (_str > 0) {
    oldarr = removeBr_Opposite_number(oldarr, indexSt)
  }

  let m = 0
  for (let i = 0; i < oldarr.length; i++) {
    if (indexSt <= i && i <= indexEd) {
      m = m + 1
      if (m == 1) {
        if (_str > 0)
          newarr.push(_str)
        else
          newarr.push(str_)
      }
    } else {
      newarr.push(oldarr[i])
    }
  }

  for (let i = 0; i < newarr.length; i++) {
    res_str = res_str + newarr[i]
  }
  // console.log("替换以后字符串是" + res_str)

  return res_str
}

function IsInt_char(char) {
  let str = Number(char)
  let bool = Number.isInteger(str);
  return bool
}
/**
 * 是否运算符
 * @param {*} char 
 */
function IsOpChar(char) {
  let arr = ["^", "/", "*", "%", "-", "+", ],
    bool = false
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] == char) bool = true
  }
  return bool
}
/**
 * 字符串是否存在某个字符
 * @param {*} string 字符串
 * @param {*} char 字符
 */
function isIndexOfchar(string, char) {
  let arr = [],
    bool = false
  for (let i = 0; i < string.length; i++) {
    arr.push(string[i])
  }
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] == char) bool = true
  }
  return bool
}